
#include "app_serial.h"

#include "termios.h"
#include "app_common.h"
#include "app_device.h"

#define _GNU_SOURCE



/**
 * @brief 串口的初始化
 *        linux一切皆文件，只要有文件的fd，就可以操作对应的文件
 *        串口设备也是文件，所以有串口文件的fd，就可以操作它
 */
returnType_t app_serial_init(Device *device)
{

    /* 0. 获取串口文件属性 */
    struct termios tm;
    if (tcgetattr(device->fd, &tm) == -1)
    {
        log_debug("tcgetattr error");
        return ERROR;
    }

    /* 1.设置波特率为9600(蓝牙模块的串口波特率为9600) */
    cfsetispeed(&tm, BAUDRATE);
    cfsetospeed(&tm, BAUDRATE);

    /* 2.设置数据大小为8bit*/
    tm.c_cflag &= ~CSIZE;
    tm.c_cflag |= CS8;

    /* 3.设置无校验位 */
    tm.c_cflag &= ~PARENB;

    /* 4.设置1位停止位 */
    tm.c_cflag &= ~CSTOPB;

    /* 5.设置为原始数据模式 */
    cfmakeraw(&tm);

    /* 6.使能属性  */
    if (tcsetattr(device->fd, TCSANOW, &tm) == -1)
    {
        log_debug("tcsetattr error");
        return ERROR;
    }

    return SUCCESS;
}

returnType_t app_serial_isblock(Device *device, int isblock)
{
    /* 0. 获取串口文件属性 */
    struct termios tm;
    if (tcgetattr(device->fd, &tm) == -1)
    {
        log_debug("tcgetattr error");
        return ERROR;
    }

    if (isblock == BLOCKING)
    {
        /* 设置串口为阻塞模式 */
        tm.c_cc[VMIN] = 1;  /* 阻塞模式，没数据不返回*/
        tm.c_cc[VTIME] = 0; /*设置超时时间。 都不返回了，无所谓超时时间*/
    }
    else
    {
        /* 设置串口为非阻塞模式 */
        tm.c_cc[VMIN] = 0;  /* 非阻塞模式*/
        tm.c_cc[VTIME] = 2; // 单元：1/10s,意思是如果超过0.2s没有等到数据就返回
    }

    /* 6.使能属性  */
    if (tcsetattr(device->fd, TCSANOW, &tm) == -1)
    {
        log_debug("tcsetattr error");
        return ERROR;
    }

    return SUCCESS;
}
